﻿#include "B3HsmsEQP.h"
#include <QDateTime>
#include <QMultiHash>

B3HsmsEQP::B3HsmsEQP(QObject *parent)
    :HsmsEQP (parent)
{
    QObject::connect(this, &HsmsDevice::dataReady, this, &B3HsmsEQP::privateDataMessage);
    registerDataMessage(1, 5);
    registerDataMessage(2, 207);//PANELINFOSET
    registerDataMessage(2, 209);
    registerDataMessage(2, 18); //DateTimeRequest
    registerDataMessage(6, 4); //DiscreteVariableDataAcknowledge
    registerDataMessage(6, 12); //EventReportAcknowledge
    registerDataMessage(6, 210);
    registerDataMessage(6, 208); //PanelInfoRequestReply
    registerDataMessage(10, 5);

    m_CRST = "2";
    m_EQST = "1";
}
void B3HsmsEQP::sendS6F3(QString PNLID, QVector<QPair<QString, QString> > data)
{
    SECS2Item siDVDATASET = buildS6F3Item(PNLID, data);
    uint32_t sb = HSMSMessages::uniqueSystemBytes();
    HSMSMessages x = HSMSMessages::dataMessage(m_sessionID, 6, 3, sb, siDVDATASET);
    x.setWBit(HSMSMessages::NeedReply);
    sendMessage(x);
}



SITESET::SITESET()
    :m_strSITENAME(""),
      m_strDV("")
{

}

SITESET::SITESET(QString SITENAME, QString DV)
    :m_strSITENAME(SITENAME),
      m_strDV(DV)
{

}

SECS2Item SITESET::toSECS2Item() const
{
    SECS2Item it("SITESET");
    SECS2Item its[2];
    its[0].setASCII(m_strSITENAME);
    its[0].setName("SITENAME");
    its[1].setASCII(m_strDV);
    its[1].setName("DV");
    it.setItems(its, 2);
    return it;
}

void SITESETLIST::clear()
{
    m_vSITESET.clear();
}

void SITESETLIST::append(class SITESET site)
{
    m_vSITESET.append(site);
}


SECS2Item SITESETLIST::toSECS2Item() const
{
    QVector<SECS2Item> vector;
    QVectorIterator<SITESET> it(m_vSITESET);
    while ( it.hasNext() )
    {
        const SITESET site = it.next();
        vector.append( site.toSECS2Item() );
    }
    SECS2Item item("SITESETLIST");
    item.setItems(vector);
    return item;
}


DVSET::DVSET(QString DVNAME, SITESETLIST sitesetList)
    :m_DVNAME(DVNAME),
      m_SITESETLIST(sitesetList)
{

}

DVSET::DVSET(QString DVNAME, SITESET siteset)
    :m_DVNAME(DVNAME),
      m_SITESETLIST(siteset)
{

}

SECS2Item DVSET::toSECS2Item() const
{
    SECS2Item DVSET_Items[2];
    DVSET_Items[0].setASCII(m_DVNAME); // 到这里是正确的
    DVSET_Items[0].setName("DVNAME");
    DVSET_Items[1] = m_SITESETLIST.toSECS2Item();
    SECS2Item DVSET("DVSET"); // LIST
    DVSET.setItems(DVSET_Items, 2);
    return DVSET;
}

void DVSETLIST::insert(QString DVNAME, QString SITENAME, QString DV)
{
    int N  = m_vDVSET.size(), i = 0;
    for(i = 0; i < N; i++)
    {
        if(DVNAME == m_vDVSET[i].DVNAME())
        {
            m_vDVSET[i].append(SITENAME, DV);
            return;
        }
    }
    if(i == N) // 说明没有同名的 DVNAME
    {
        append(DVSET(DVNAME, SITESET(SITENAME, DV)));
    }
    return;
}

SECS2Item DVSETLIST::toSECS2Item() const
{
    QVector<SECS2Item> vector;
    QVectorIterator<DVSET> it(m_vDVSET);

    while ( it.hasNext() )
    {
        const DVSET dvset = it.next();
        vector.append( dvset.toSECS2Item() );
    }
    SECS2Item dvsetList("DVSETLIST"); // LIST
    dvsetList.setItems(vector);
    return dvsetList;
}

SECS2Item DATASET::toSECS2Item() const
{
    SECS2Item DATASET_Items[4];
    DATASET_Items[0].setASCII(m_strEQPID); // 到这里是正确的
    DATASET_Items[0].setName("EQPID");
    DATASET_Items[1].setASCII(m_strUNITID);
    DATASET_Items[1].setName("UNITID");
    DATASET_Items[2].setASCII(m_strPNLID);
    DATASET_Items[2].setName("PNLID");
    DATASET_Items[3] = m_DVSETLIST.toSECS2Item();
    SECS2Item dataSet("DATASET"); // LIST
    dataSet.setItems(DATASET_Items, 4);
    return dataSet;
}

SECS2Item DVDATASET::toSECS2Item() const
{
    SECS2Item DVDATASET_Items[2];
    DVDATASET_Items[0].setASCII(m_strCEID);
    DVDATASET_Items[1] = m_DATASET.toSECS2Item();
    SECS2Item dvdataSet("DVDATASET"); // LIST
    dvdataSet.setItems(DVDATASET_Items, 2);
    return dvdataSet;
}


SECS2Item B3HsmsEQP::buildS6F3ItemTest()
{
    DVSETLIST dvsetList;
    dvsetList.insert("CG01", "COG_GATE_X", "1");
    dvsetList.insert("CG01", "COG_GATE_Y", "2");
    dvsetList.insert("CG01", "COG_SOURCE_X", "3");
    dvsetList.insert("CG01", "COG_SOURCE_Y", "4");
    dvsetList.insert("FS01", "FOG_SOURCE", "5");
    dvsetList.insert("TFS02", "TFOG_SOURCE", "6");

    DATASET dataset(m_EQPID, m_UNITID, "3AUE090016A4BM", dvsetList);
    DVDATASET dvDataSet("501", dataset);

    return dvDataSet.toSECS2Item();

}
SECS2Item B3HsmsEQP::buildS6F3Item(QString PNLID,
                    QVector< QPair<QString, QString> > data)
{
    DVSETLIST dvsetlist;
    int N = data.size();
    DVSETLIST dvsetList;
    for(int i = 0; i < N; i++)
    {
        QString dvName;
        QString siteName;
        QString value = data[i].second;
        QStringList list = data[i].first.split(".");
        if(list.size() == 2)
        {
            dvName = list[0];
            siteName = list[1];
        }
        dvsetList.insert(dvName, siteName, value);
    }

    DATASET dataset(m_EQPID, m_UNITID, PNLID, dvsetList);
    DVDATASET dvDataSet("501", dataset); // CEID = 501

    return dvDataSet.toSECS2Item();
}

void B3HsmsEQP::onReceiveS6F210(const HSMSMessages &message)
{
    SECS2Item it = message.getItem();
    QString str = it.toASCII();

    qDebug() << "OperatorAuthorityRequestReply = " << str;
}

void B3HsmsEQP::onReceiveS6F208(const HSMSMessages &message)
{
    SECS2Item it = message.getItem();
    QString str = it.toASCII();

    qDebug() << "PanelInfoRequestReply = " << str;
}

void B3HsmsEQP::onReceiveS2F209(const HSMSMessages &message)
{
    SECS2Item it = message.getItem();
    QVector<SECS2Item> AUTHORITYSET = it.toItems();
    QString EQPID = AUTHORITYSET[0].toASCII();
    QString UNITID = AUTHORITYSET[1].toASCII();
    QString OPERATORID = AUTHORITYSET[2].toASCII();
    QString AUTHORITYCODE = AUTHORITYSET[3].toASCII();

    HSMSMessages m = HSMSMessages::replyDataMessage(message, "0"); //OperatorAuthorityDownloadReply
    sendMessage(m);

    if(AUTHORITYCODE == "0")
    {
        emit loginStatus(true);
        return;
    }
    qDebug() << "ID or Password is wrong!";
    emit loginStatus(false);
    return;
}

void B3HsmsEQP::onReceiveS6F4(const HSMSMessages &message)
{
    Q_UNUSED(message);
    //TODO: 这里暂时什么都不做。后续会增加超时重发机制。这里就需要增加功能了。
}

void B3HsmsEQP::onReceiveS10F5(const HSMSMessages &message)
{
    qDebug() << "S10F5: Do nothing, only reply.";
    HSMSMessages rsp = HSMSMessages::replyDataMessage(message, "0"); //TerminalDisplayMultiBlockAcknowledge
    sendMessage(rsp);
}

void B3HsmsEQP::privateDataMessage(const HSMSMessages &message)
{
    uint8_t stream = message.stream();
    uint8_t function = message.function();
    if(stream == 2 && function == 207) //PANELINFOSET
    {
        onReceiveS2F207(message);
        return;
    }
    if(stream == 6 && function == 12) //EventReportAcknowledge
    {
        onReceiveS6F12(message);
        return;
    }
    if(stream == 2 && function == 18) //Date and time data
    {
        onReceiveS2F18(message);
        return;
    }
    if(stream == 1 && function == 5) //Formatted status request
    {
        onReceiveS1F5(message);
        return;
    }
    if(stream == 6 && function == 210) //OperatorAuthorityRequestReply
    {
        onReceiveS6F210(message);
        return;
    }
    if(stream == 6 && function == 4) //DiscreteVariableDataAcknowledge
    {
        onReceiveS6F4(message);
        return;
    }
    if(stream == 2 && function == 209) //
    {
        onReceiveS2F209(message);
        return;
    }
    if(stream == 6 && function == 208) //PanelInfoRequestReply
    {
        onReceiveS6F208(message);
        return;
    }
    if(stream == 10 && function == 5) //Terminal display, multi-block
    {
        onReceiveS10F5(message);
        return;
    }

}

void B3HsmsEQP::sendS6F207(QString PNLID)
{
    SECS2Item its[4];
    its[0].setASCII(m_EQPID);
    its[1].setASCII(m_UNITID);
    its[2].setASCII(PNLID);
    its[3].setASCII(m_MODULEID);
    SECS2Item PANELINFOSET;
    PANELINFOSET.setItems(its, 4);

    uint32_t sb = HSMSMessages::uniqueSystemBytes();
    HSMSMessages x = HSMSMessages::dataMessage(m_sessionID, 6, 207, sb, PANELINFOSET);
    x.setWBit(HSMSMessages::NeedReply);
    sendMessage(x);
}

void B3HsmsEQP::sendS6F209(QString OPERATORID, QString PASSWORD)
{
    SECS2Item its[4];
    its[0].setASCII(m_EQPID);
    its[1].setASCII(m_UNITID);
    its[2].setASCII(OPERATORID);
    its[3].setASCII(PASSWORD);

    SECS2Item AUTHORITYINFOSET;
    AUTHORITYINFOSET.setItems(its, 4);

    uint32_t sb = HSMSMessages::uniqueSystemBytes();
    HSMSMessages x = HSMSMessages::dataMessage(m_sessionID, 6, 209, sb, AUTHORITYINFOSET);
    x.setWBit(HSMSMessages::NeedReply);
    sendMessage(x);
}

void B3HsmsEQP::sendS6F11()
{
    SECS2Item CRST[1];
    CRST[0].setASCII("1"); //CRST
    SECS2Item CREQSET[2];
    CREQSET[0].setASCII("111");  //CREQRPTID
    CREQSET[1].setItems(CRST, 1);//CREQSET
    SECS2Item CREQRPTSET;
    CREQRPTSET.setItems(CREQSET, 2); //CREQRPTSET
    SECS2Item RPTIDLIST[3];
    RPTIDLIST[0].setASCII("1");  //DATAID
    RPTIDLIST[1].setASCII("112"); //CEID
    RPTIDLIST[2].setItems(&CREQRPTSET, 1); //RPTIDLIST
    SECS2Item EVENTREPORTSET;
    EVENTREPORTSET.setItems(RPTIDLIST, 3); //EVENTREPORTSET
    uint32_t sb = HSMSMessages::uniqueSystemBytes();
    HSMSMessages x = HSMSMessages::dataMessage(m_sessionID, 6, 11, sb, EVENTREPORTSET);
    x.setWBit(HSMSMessages::NeedReply);
    sendMessage(x);
}

void B3HsmsEQP::onReceiveS2F18(const HSMSMessages &message)
{
    SECS2Item it = message.getItem();
    QString str = it.toASCII();
    QDateTime t = QDateTime::fromString(str, "yyyyMMddhhmmss");

    emit dateTimeReplyReceived(t);
    qDebug() << "DateTime from Host is " << t;
}

void B3HsmsEQP::onReceiveS1F5(const HSMSMessages &message)
{
    SECS2Item it = message.getItem();
    QString SFCD = it.toASCII();

    SECS2Item its[3];
    its[0].setASCII(m_EQPID);
    its[1].setASCII(m_CRST);
    its[2].setASCII(m_EQST);

    SECS2Item CREQSET;
    CREQSET.setItems(its, 3);

    SECS2Item its2[2];
    its2[0].setASCII(SFCD);
    its2[1].setItems(&CREQSET, 1);

    SECS2Item SFCDSET;
    SFCDSET.setItems(its2, 2);

    HSMSMessages rsp = HSMSMessages::replyDataMessage(message, SFCDSET);
    sendMessage(rsp);
}

void B3HsmsEQP::onReceiveS6F12(const HSMSMessages &message)
{
    SECS2Item it = message.getItem();
    QString str = it.toASCII();
    qDebug() << "Receive S6F12: ACKC6 = " << str;

    if(str == "0")
    {
        emit onlineLocal(true);
        return;
    }
    emit onlineLocal(false);
    return;
}

void B3HsmsEQP::onReceiveS2F207(const HSMSMessages &message)
{
    SECS2Item it = message.getItem();
    QVector<SECS2Item> its = it.toItems();
    QString RTCODE = its[0].toASCII();
    QString EQPID = its[1].toASCII();
    QString UNITID = its[2].toASCII();
    QString PNLID = its[3].toASCII();
    QString MODULEID = its[4].toASCII();
    QString FGCODE = its[5].toASCII();
    QString WORKORDER = its[6].toASCII();
    QString PNLJUDGE = its[7].toASCII();
    QString PNLGRADE = its[8].toASCII();
    QString REASONCODE = its[9].toASCII();
    QString CURRENTSTEP = its[10].toASCII();
    QString GROUPID = its[11].toASCII();
    QString INSPFILENAME = its[12].toASCII();
    QString INSPFILEPATH = its[13].toASCII();
    QString REVISION = its[14].toASCII();
    QString CELLGRADE = its[15].toASCII();
    QString WOGRADE = its[16].toASCII();

    m_PANELINFOSET.clear();
    m_PANELINFOSET.insert("PNLID", PNLID);
    m_PANELINFOSET.insert("FGCODE", FGCODE);
    m_PANELINFOSET.insert("UNITID", UNITID);
    m_PANELINFOSET.insert("MODULEID", MODULEID);
    m_PANELINFOSET.insert("WORKORDER", WORKORDER);
    m_PANELINFOSET.insert("PNLJUDGE", PNLJUDGE);
    m_PANELINFOSET.insert("PNLGRADE", PNLGRADE);
    m_PANELINFOSET.insert("REASONCODE", REASONCODE);
    m_PANELINFOSET.insert("CURRENTSTEP", CURRENTSTEP);
    m_PANELINFOSET.insert("GROUPID", GROUPID);
    m_PANELINFOSET.insert("INSPFILENAME", INSPFILENAME);
    m_PANELINFOSET.insert("INSPFILEPATH", INSPFILEPATH);
    m_PANELINFOSET.insert("REVISION", REVISION);
    m_PANELINFOSET.insert("CELLGRADE", CELLGRADE);
    m_PANELINFOSET.insert("WOGRADE", WOGRADE);

    HSMSMessages rsp = HSMSMessages::replyDataMessage(message, "0"); //PanelInfoDownloadReply
    sendMessage(rsp);

    if(RTCODE == "0")
    {
        emit panelInfoUpdated(true);
    }
    else {
        emit panelInfoUpdated(false);
    }
}

QString B3HsmsEQP::getPanelInfo(QString itemName)
{
    return m_PANELINFOSET.value(itemName, "");
}
